package idoc.handOn.workshop.service.impl;

import idoc.handOn.workshop.model.Word;
import idoc.handOn.workshop.service.WordFactory;
import idoc.handOn.workshop.service.WordService;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Set;


public class WordFactoryImpl implements WordFactory {
	
	public WordService wordService = new WordServiceImpl();
	
	@Override
	public boolean process(String inputOne, String inputTwo, String output) throws FileNotFoundException {
		
		boolean success = false;
		File fileOne = new File(inputOne);
		File fileTwo = new File(inputTwo);
		
		if (fileOne.exists() && fileTwo.exists()) {
			List<Word> commonWords = getCommonFiles(fileOne, fileTwo);
			BufferedWriter writer = null;
			
			// valides common words
			if (commonWords == null || commonWords.isEmpty())
				return false;
				
			try {
				File outputFile = new File(output);
				if (!outputFile.exists()) {
					outputFile.createNewFile();
				}
				orderWords(commonWords);
				
				writer = new BufferedWriter(new FileWriter(output));
				
				// write to file
				for (Word word : commonWords) {
					writer.write(word.getWord());
					writer.newLine();
				}
				success = true;
			} catch (Exception e) {
				e.printStackTrace();
				success = false;
			} finally {
				closeWriter(writer);
			}
		}
		else {
			success = false;
			throw new FileNotFoundException("Cannot find files: " + inputOne + " and/or " + inputTwo);
		}

		return success;
	}

	public void closeWriter(BufferedWriter writer) {
		if (writer != null) {
			try {
				writer.flush();
				writer.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	@Override
	public void orderWords(List<Word> words) {
		Collections.sort(words, new Comparator<Word>() {
			@Override
			public int compare(Word o1, Word o2) {
				return o1.getWord().compareTo(o2.getWord());
			};
		});
		
	}

	public List<Word> getCommonFiles(File fileOne, File fileTwo) {
		Set<Word> fileOneUniqueWords = wordService.getWords(fileOne);
		Set<Word> fileTwoUniqueWords = wordService.getWords(fileTwo);
		
		List<Set<Word>> wordList =  new ArrayList<Set<Word>>();
		wordList.add(fileOneUniqueWords);
		wordList.add(fileTwoUniqueWords);
		
		List<Word> commonWords = wordService.loadCommonWords(wordList);
		return commonWords;
	}
}
